home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / MacApp Release 10 / MacApp Release 10 - HD Ready / Libraries / Core / Sources / UPatch.cp < prev    next >
Encoding:
Text File  |  1996-04-03  |  7.2 KB  |  270 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. // UPatch.cp 
  3. // Copyright © 1985-96 by Apple Computer, Inc. All rights reserved. 
  4. //----------------------------------------------------------------------------------------
  5.  
  6. #ifndef __UPATCH__
  7. #include "UPatch.h"
  8. #endif
  9.  
  10. // MacApp
  11.  
  12. #ifndef __UFAILURE__
  13. #include "UFailure.h"
  14. #endif
  15.  
  16. #ifndef __UCOREUTILITIES__
  17. #include "UCoreUtilities.h"
  18. #endif
  19.  
  20. #ifndef __UMEMORY__
  21. #include "UMemory.h"
  22. #endif
  23.  
  24. // Toolbox
  25.  
  26. #if qPowerPC
  27.     #ifndef __FRAGLOAD__
  28.     #include <FragLoad.h>
  29.     #endif
  30. #endif
  31.     
  32. #ifndef __GESTALTEQU__
  33. #include <GestaltEqu.h>
  34. #endif
  35.  
  36. #ifndef __LOWMEM__
  37. #include <LowMem.h>
  38. #endif
  39.  
  40. #ifndef __MEMORY__
  41. #include <Memory.h>
  42. #endif
  43.  
  44. #ifndef __OSUTILS__
  45. #include <OSUtils.h>
  46. #endif
  47.  
  48. #if qPowerPC
  49.     #ifndef __RESOURCES__
  50.     #include <Resources.h>
  51.     #endif
  52. #endif
  53.  
  54. #ifndef __TEXTEDIT__
  55. #include <TextEdit.h>
  56. #endif
  57.  
  58. #ifndef __TRAPS__
  59. #include <Traps.h>
  60. #endif
  61.  
  62. // ANSI
  63.  
  64. #ifndef __STDIO__
  65. #include <stdio.h>
  66. #endif
  67.  
  68. //----------------------------------------------------------------------------------------
  69.  
  70. TrapPatchPtr TrapPatch::pPatchList;                    // global allocation declared in my header
  71.  
  72. //----------------------------------------------------------------------------------------
  73. // PatchTrap: 
  74. //----------------------------------------------------------------------------------------
  75. #pragma segment MAPatchRes
  76.  
  77. TrapPatch::TrapPatch()
  78. {
  79.     trapNum = 0;
  80.     oldTrapAddr = NULL;
  81.     patchRoutine = NULL;
  82.     nextPatch = NULL;
  83. }
  84.  
  85. //----------------------------------------------------------------------------------------
  86. // PatchTrap: 
  87. //----------------------------------------------------------------------------------------
  88. #pragma segment MAPatchRes
  89.  
  90. short TrapPatch::PatchTrap(short theTrapNum, void* theRoutine)
  91. {
  92.     LookupOldTrapAddress(theTrapNum);
  93.     trapNum = theTrapNum;
  94.     nextPatch = pPatchList;
  95.     pPatchList = this;
  96.     NSetTrapAddress((UniversalProcPtr)theRoutine, theTrapNum, GetTrapType(theTrapNum));
  97.     return noErr;
  98. } // PatchTrap 
  99.  
  100. //----------------------------------------------------------------------------------------
  101. // LookupOldTrapAddress:
  102. //----------------------------------------------------------------------------------------
  103. #pragma segment MAPatchRes
  104.  
  105. void TrapPatch::LookupOldTrapAddress(short theTrapNum)
  106. {
  107.     oldTrapAddr = NGetTrapAddress(theTrapNum, GetTrapType(theTrapNum));
  108. } // LookupOldTrapAddress 
  109.  
  110. //----------------------------------------------------------------------------------------
  111. // GetPreviousPatchPtr: walks the patch list backwards to return the patch record just
  112. // prior to (*thePatchPtr) in the patch list
  113. //----------------------------------------------------------------------------------------
  114. #pragma segment MAPatchRes
  115.  
  116. TrapPatchPtr TrapPatch::GetPreviousPatchPtr(void)
  117. {
  118.     TrapPatchPtr tempPatchPtr = pPatchList;
  119.  
  120.     if (tempPatchPtr == this)
  121.         return NULL;
  122.     while ((tempPatchPtr != NULL) && (tempPatchPtr->nextPatch != this))
  123.         tempPatchPtr = tempPatchPtr->nextPatch;
  124.     return tempPatchPtr;
  125. } // GetPreviousPatchPtr 
  126.  
  127. //----------------------------------------------------------------------------------------
  128. // GetNewerPatchPtr: returns a newer patch record in the patch list which has the *same*
  129. // trapNum as thePatch
  130. //----------------------------------------------------------------------------------------
  131. #pragma segment MAPatchRes
  132.  
  133. TrapPatchPtr TrapPatch::GetNewerPatchPtr(void)
  134. {
  135.     TrapPatchPtr newerPatch = NULL;
  136.     TrapPatchPtr tempPatchPtr = pPatchList;
  137.  
  138.     while ((tempPatchPtr != NULL) && (tempPatchPtr != this))
  139.     {
  140.         if (tempPatchPtr->trapNum == trapNum)
  141.             newerPatch = tempPatchPtr;
  142.         tempPatchPtr = tempPatchPtr->nextPatch;
  143.     }
  144.     return newerPatch;
  145. } // GetNewerPatchPtr 
  146.  
  147.  
  148. //----------------------------------------------------------------------------------------
  149. // UnpatchTrap: 
  150. //----------------------------------------------------------------------------------------
  151. #pragma segment MAPatchRes
  152.  
  153. void TrapPatch::UnpatchTrap(void)
  154. {
  155.     // You can't patch nothing, so we use the old trap address to keep track of if we
  156.     // have a patch installed. 
  157.     if (oldTrapAddr == NULL)
  158.         return;
  159.     
  160.     // If this trap has a newer patch than the patch we're removing, then we have to take
  161.     // some extra special precautions. We have to muck with that patch's oldTrapAddr to
  162.     // point to this patch record's oldTrapAddr. We can pretty well ignore the case of
  163.     // an older patch on this same trap since the trapaddress in our patch record will
  164.     // be correct.
  165.     
  166.     // only set the trap address if there *isn't* a newer patch
  167.     TrapPatchPtr newerPatchPtr = GetNewerPatchPtr();
  168.     if (newerPatchPtr == NULL)
  169.         NSetTrapAddress(oldTrapAddr, trapNum, GetTrapType(trapNum));
  170.     else
  171.     {
  172.         // set up newerPatchPtr patch record so that it points to thePatch's OldTrapAddr 
  173.         newerPatchPtr->oldTrapAddr = oldTrapAddr;
  174.     }
  175.     oldTrapAddr = NULL;
  176.     
  177.     if (patchRoutine)
  178.     {
  179.         DisposeRoutineDescriptor(patchRoutine);
  180.         patchRoutine = NULL;
  181.     }
  182.  
  183.     // Unlink the patch from the linked list of patches 
  184.     if (this == pPatchList)
  185.         pPatchList = nextPatch;
  186.     else
  187.     {
  188.         TrapPatchPtr aPatchPtr = GetPreviousPatchPtr();
  189.         if (aPatchPtr != NULL)                    // Couldn't find thePatch, don't unpatch it
  190.             aPatchPtr->nextPatch = nextPatch;
  191.     }
  192.     nextPatch = NULL;
  193.     
  194. } // UnpatchTrap 
  195.  
  196. //----------------------------------------------------------------------------------------
  197. // FlushCache: 
  198. //----------------------------------------------------------------------------------------
  199. #pragma segment MAPatchRes
  200.  
  201. void FlushCache()
  202. {
  203. #if !qPowerPC
  204.     // Flush the instruction and data cache, if traps are enabled.
  205.     long OldA5 = SetCurrentA5();    // ***** May be called from trap patches *****
  206.     if (TrapExists(_HWPriv))
  207.     {
  208.         FlushDataCache();
  209.         FlushInstructionCache();
  210.     }
  211.     SetA5(OldA5);
  212. #endif
  213. } // FlushCache 
  214.  
  215. #if !qPowerPC
  216. //----------------------------------------------------------------------------------------
  217. // PatchJmpInstruction: 
  218. //----------------------------------------------------------------------------------------
  219. #pragma segment MAPatchRes
  220.  
  221. void PatchJmpInstruction(void* patchAddress, void* jumpAddress)
  222. {
  223.     JmpInstructionTemplate*    aJmpInstructionPtr = (JmpInstructionTemplate *) patchAddress;
  224.     aJmpInstructionPtr->Jmp = 0x4EF9;
  225.     aJmpInstructionPtr->Routine = jumpAddress;
  226.  
  227.     FlushCache();
  228. } // PatchJmpInstruction 
  229.  
  230. #endif
  231.  
  232. //----------------------------------------------------------------------------------------
  233. // UnpatchAll: 
  234. //----------------------------------------------------------------------------------------
  235. #pragma segment MAPatchRes
  236.  
  237. void TrapPatch::UnpatchAll(void)
  238. {
  239.     while (pPatchList != NULL)
  240.     {
  241.         pPatchList->UnpatchTrap();
  242.     }
  243. }
  244.  
  245.  
  246. #if !qPowerPC
  247. //----------------------------------------------------------------------------------------
  248. // SetCallBack: 
  249. //----------------------------------------------------------------------------------------
  250. #pragma segment MAPatchRes
  251.  
  252. void SetCallBack(void* targProc, long itsRefCon, CallBackPtr theCallBackPtr)
  253. {
  254.     theCallBackPtr->saveRtnAdd = 0x2F17;
  255.     theCallBackPtr->moveRefCon = 0x2F7C;
  256.     theCallBackPtr->refCon = itsRefCon;
  257.     theCallBackPtr->targOffset = 0x0004;
  258.     theCallBackPtr->jmpInst = 0x4EF9;
  259.     theCallBackPtr->jmpTarg = targProc;
  260.  
  261.     FlushCache();
  262. } // SetCallBack 
  263.  
  264. #endif
  265.  
  266. //----------------------------------------------------------------------------------------
  267. // End of UPatch.cp
  268.  
  269. #pragma segment Inline
  270.